#pragma once

#include <string>
#include <stdexcept>

#include <GL\glew.h>
#include <GL\freeglut.h>

#include "ShaderLoader.h"
#include "IRenderizable.h"


// Todo lo que puede necesitar un elemento para ser dibujado en pantalla
class Renderizable : public IRenderizable {
public:
	Renderizable();
	virtual ~Renderizable();

	// Inicializa el elemento y setea la posicion de la luz direccional
	virtual void init(const glm::vec3 &posFuenteLuzDireccional, std::string vertShaderFileName, std::string fragShaderFileName);

	// Permite setear los coeficientes usados en la iluminacion del elemento
	virtual void setMaterial(const glm::vec3 &coefDifusion, const glm::vec3 &coefAmbiente, const glm::vec3 &coefEspecular);

	// Dibuja en pantalla el elemento usando las matrices de transformacion pasadas
	virtual void renderizar(const glm::mat4 &matVista, const glm::mat4 &matProyeccion, const glm::mat4 &matModelo) const = 0;

protected:
	// Carga el shader program y devuelve su ID por si alguien lo quiere usar
	virtual GLuint cargarShaderProgram() const;

	// Carga las matrices de transformacion en el shader, el "shaderProgramID" debe estar cargado 
	virtual void cargarMatricesTransformacion(const glm::mat4 &viewMat, const glm::mat4 &projectionMat, const glm::mat4 &modelMat) const;

	// Carga los datos necesarias para la iluminacion del elemento, el "shaderProgramID" debe estar cargado 
	virtual void cargarDatosIluminacion(const glm::mat4 &matModel) const;

private:
	// Los datos de la iluminacion
	glm::vec3 m_coefDifuso;
	glm::vec3 m_coefAmbiente;
	glm::vec3 m_coefEspecular;

	glm::vec3 m_posLuzDireccional;

	// El encargado de manejar los shaders
	ShaderLoader m_shaders;
};

